package sui.template
{

    /**
     * @author feiyu
     *
     * <pre>
     * {$name} 引用变量
     * {$num + $num2 * 2} 简单的数学表达式 +-* /%
     * {$obj.attribute} 引用变量属性
     * {$obj.attribute.prop} 引用变量属性
     * {#package.path.Class.staticVar.attribute}
     * {$name|default:'no title'}
     * {$date|date:'hh:mm:ss'}
     * {$sui.now|date:'hh:mm:ss'} 时间戳
     * {$L.UNTITLED} 语言包
     * </pre>
     */
    public class Template
    {
        private var segments:Array = [];

        public function Template(pattern:String)
        {
            parse(pattern);
        }

        protected function parse(str:String):void
        {
            var right:int = -1
            var left:int = 0;
            var cursor:int = 0;
            for (; ; )
            {
                left = str.indexOf("{", ++right);
                if (left == -1)
                {
                    if (right < str.length - 1)
                    {
                        segments.push(str.substring(right))
                    }
                    break;
                }
                right = str.indexOf("}", ++left);
                if (right == -1)
                {
                    throw new Error("{} not pair");
                }
                if (left - cursor > 1)
                {
                    segments.push(str.substring(cursor, left - 1))
                }
                segments.push(ExpressionFactory.create(str.substring(left, right), arguments.callee));
                cursor = right + 1;
            }
        }

        public function generate(context:Object):String
        {
            var res:String = "";
            for (var i:int = 0; i < segments.length; i++)
            {
                if (segments[i] is String)
                {
                    res += segments[i];
                }
                else
                {
                    res += IExpression(segments[i]).exec(context);
                }
            }
            return res;
        }
    }
}
